package gamebook;

import java.sql.SQLException;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import persistencia.PUsuarioGenerico;

public abstract class UsuarioGenerico {

    public static final int USUXPAG = 5;
    private int id;
    private String nombre;
    private String apellidos;
    private String mail;
    private Date nacimiento;
    private String sexo;
    private String password;
    private String localidad;

    public UsuarioGenerico() {
        //Constructor Vacio
    }

    public UsuarioGenerico(String nombre, String apellidos, String mail, Date nacimiento, String sexo, String password, String localidad) {
        this.nombre = nombre;
        this.apellidos = apellidos;
        this.mail = mail;
        this.nacimiento = nacimiento;
        this.sexo = sexo;
        this.password = password;
        this.localidad = localidad;
    }

    public UsuarioGenerico(int id, String nombre, String apellidos, String mail, Date nacimiento, String sexo, String password, String localidad) {
        this.id = id;
        this.nombre = nombre;
        this.apellidos = apellidos;
        this.mail = mail;
        this.nacimiento = nacimiento;
        this.sexo = sexo;
        this.password = password;
        this.localidad = localidad;
    }
    
    

    public String getApellidos() {
        return apellidos;
    }

    public void setApellidos(String apellidos) {
        this.apellidos = apellidos;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getLocalidad() {
        return localidad;
    }

    public void setLocalidad(String localidad) {
        this.localidad = localidad;
    }

    public String getMail() {
        return mail;
    }

    public void setMail(String mail) {
        this.mail = mail;
    }

    public Date getNacimiento() {
        return nacimiento;
    }

    public void setNacimiento(Date nacimiento) {
        this.nacimiento = nacimiento;
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getSexo() {
        return sexo;
    }

    public void setSexo(String sexo) {
        this.sexo = sexo;
    }

    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    /**
     * Devuelve un usuario a traves de su mail siempre que el password coincida
     * con el del usuario. Se utiliza para la validación al entrar en la web.
     * @param mail
     * @param password
     * @return Devolverá el UsuarioGenerico cuyo mail sea el que hemos pasado o
     * null si falló la validación, ya sea porque el mail no existe o el password
     * estaba mal.
     */
    public static UsuarioGenerico validarUsuario(String mail, String password) {
        UsuarioGenerico usuarioGenerico = null;
        //Pedimos el usuario con el mail requerido
        usuarioGenerico = PUsuarioGenerico.seleccionarPorMailBD(mail);
        //Si no existe devolvemos null
        if (usuarioGenerico == null) {
            return null;
        }
        //Comparamos el password del usuario con el que nos han pasado
        if (usuarioGenerico.getPassword().equals(password)) {
            return usuarioGenerico; //Correcto, devolvemos el usuario
        } else {
            return null; //Mal, devolvemos null
        }
    }

    /**
     * Obtiene una lista de usuarios por su nombre o apellido en general. Se puede
     * usar para buscar contactos por el nombre o apellido y agregarlo como amigo.
     * @param nombre nombre o apellido o parte de alguno de ellos
     * @return una lista de usuarios o null si no hay ninguno que cumpla el criterio
     */
    public static List<UsuarioGenerico> getUsuariosGenericosPorNombre(String nombre,UsuarioGenerico u,boolean amistad,int inicio, int cantidad) {
        List<UsuarioGenerico> listUsuarios = null;
        if(amistad){
            listUsuarios = PUsuarioGenerico.seleccionarPorNombreBDAmigos(u, nombre, inicio, cantidad);
        }else{
            listUsuarios = PUsuarioGenerico.seleccionarPorNombreBD(u,nombre,inicio, cantidad);
        }
        
        return listUsuarios;
    }
    
    
    public static int cuentaUsuarios(UsuarioGenerico u,String nombre,int opc) throws SQLException{
        int retorno=0;
        if(opc==1){
            retorno = PUsuarioGenerico.cuentaPorNombreBD(u, nombre);
        }else if(opc==2){
            retorno = PUsuarioGenerico.cuentaPorNombreBDAmigos(u, nombre);
        }
        return retorno;
    }
    
    /**
     * Obtiene el usuario por su mail. Se puede
     * usar para buscar contactos por el nombre o apellido y agregarlo como amigo.
     * @param nombre nombre o apellido o parte de alguno de ellos
     * @return una lista de usuarios o null si no hay ninguno que cumpla el criterio
     */
    public static UsuarioGenerico getUsuarioPorMail(String mail) {
        return PUsuarioGenerico.seleccionarPorMailBD(mail);
    }

    /**
     * Obtiene el usuario por su id.
     * @param nombre nombre o apellido o parte de alguno de ellos
     * @return una lista de usuarios o null si no hay ninguno que cumpla el criterio
     */
    public static UsuarioGenerico getUsuarioPorId(int id) {
        return PUsuarioGenerico.seleccionarPorIdBD(id);
    }

    /**
     * Da de alta al usuario en la base de datos. Este método simplemente le pasa
     * el objeto UsuarioGenerico a la capa de persistencia usando el 'this'.
     * Además, después de guardar el usuario, se le asignará la Id con la que se guardó.
     * @return true o false según se haya guardado correctamente o no
     */
    public boolean darAlta() {
        return PUsuarioGenerico.darAltaBD(this);
    }

    /**
     * Actualiza los datos de un usuario en la base de datos. Este método simplemente
     * le pasa el objeto UsuarioGenerico a la capa de persistencia usando el 'this'.
     * @return true o false según se haya guardado correctamente o no
     */
    public boolean actualizar() {
        return PUsuarioGenerico.actualizarBD(this);
    }
    
    /**
     * Método estático de la clase para saber si un mail está en uso o está libre.
     * @param mail e-mail que queremos comprobar si está en uso
     * @return true o false según si está en uso o no el mail
     */
    public static boolean existeMail(String mail) {
        boolean enUso = true;
        UsuarioGenerico usuarioGenerico = null;
        //Pedimos el usuario con el mail requerido
        usuarioGenerico = PUsuarioGenerico.seleccionarPorMailBD(mail);
        //Si obtenemos un usuario, es que está en uso y si obtenemos null está libre
        if (usuarioGenerico == null) {
            enUso = false;
        }
        return enUso;
    }
    /*
     * Este metodo nos quita un usuario de la lista de usuarios. Nos sirve para eliminar 
     * el usuario que esta en la sesion de la lista de usuarios que se muestran en las busquedas
     * 
     * @param listUsuarios de usuario que filtraremos
     * @return listUsuarios, devuelve la lista filtrada
     */
    public List<UsuarioGenerico> filtraUsuarioSesion(List<UsuarioGenerico> listUsuarios){
        Iterator it = listUsuarios.iterator();
        boolean encontrado = false;
        while(it.hasNext() && !encontrado){
            UsuarioGenerico u = (UsuarioGenerico)it.next();
            if(u.getMail().equals(this.getMail())){
                it.remove();
                encontrado = true;
            }
        }
        return listUsuarios;
    }
    
    public boolean esAmigo(UsuarioGenerico usuario) throws SQLException{
        return PUsuarioGenerico.esAmigo(this, usuario);
    }
    
    public String getEdad(){
        Calendar calNacimiento = new GregorianCalendar();
        Calendar calActual = new GregorianCalendar();
        
        calNacimiento.setTime(getNacimiento());
        calActual.setTime(new Date());
        
        
        String anyos = "" + (calActual.get(Calendar.YEAR) - calNacimiento.get(Calendar.YEAR));
        
        return anyos;
    }
    public boolean invitar(UsuarioGenerico usuarioDestino) throws SQLException{
        return PUsuarioGenerico.invitar(this,usuarioDestino);
    }
    public void respuestaInvitacion(UsuarioGenerico usuarioInvitador,boolean acepta) throws SQLException{
       PUsuarioGenerico.respuestaInvitacion(usuarioInvitador,this,acepta);
    }
    public int numeroNuevasInvitaciones() throws SQLException{
        return PUsuarioGenerico.numeroNuevasInvitaciones(this);
    }
    //Obtiene de la ultima invitacion que ha recibido, el id del usuario que la realizó
    
    public int getIDPersonaQueInvita() throws SQLException{
        return PUsuarioGenerico.getIDPersonaQueInvita(this);
    }
    
    public UsuarioGenerico getPersonaQueInvita() throws SQLException{
        int id = getIDPersonaQueInvita();
        return getUsuarioPorId(id);
    }
    
    public void borraAmigo(UsuarioGenerico usuarioEliminado) throws SQLException, Exception{
        PUsuarioGenerico.borraAmigo(this, usuarioEliminado);
    }
    
    /**
     * Obtiene una lista de los usuarios que han invitado al usuario en cuestión
     * a ser amigos.
     * @return una lista de usuarios que han invitado al usuario a ser amigos
     */
    public List<UsuarioGenerico> seleccionarUsuariosGenericosQueInvitaron() {
        List<UsuarioGenerico> listUsuarios = null;
        listUsuarios = PUsuarioGenerico.seleccionarUsuariosGenericosQueInvitaronBD(this);
        return listUsuarios;
    }

}
